package ext.tianma.bom.expand.service;

import java.io.IOException;
import java.io.Serializable;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.apache.log4j.Logger;

import wt.doc.WTDocument;
import wt.fc.ObjectReference;
import wt.fc.PersistenceHelper;
import wt.fc.PersistentReference;
import wt.fc.ReferenceFactory;
import wt.fc.WTReference;
import wt.fc.collections.WTArrayList;
import wt.log4j.LogR;
import wt.method.RemoteAccess;
import wt.org.WTUser;
import wt.part.WTPart;
import wt.session.SessionHelper;
import wt.util.WTException;
import wt.util.WTMessage;
import wt.util.WTProperties;
import wt.workflow.engine.ProcessData;
import wt.workflow.engine.WfProcess;
import wt.workflow.work.WfAssignedActivity;
import wt.workflow.work.WorkItem;

import com.ptc.core.components.forms.FormProcessingStatus;
import com.ptc.core.components.forms.FormResult;
import com.ptc.netmarkets.util.beans.NmCommandBean;
import com.ptc.netmarkets.util.misc.NmContext;

import ext.com.core.CoreUtil;
import ext.com.iba.IBAUtil;
import ext.tianma.bom.expand.build.MaterielTableBuilder;
import ext.tianma.bom.expand.constant.MaterielConstant;
import ext.tianma.bom.workflow.SendEmailNotification;
import ext.tianma.workflow.BomWorkFlowUtil;

public class MaterielService implements RemoteAccess, Serializable{

	private static final long serialVersionUID = 4712983168278186621L;
	

	private static final Logger logger = LogR.getLogger(MaterielService.class.getName());
	
	/**
	 * 手动取消受控
	 * @param nmcommandbean
	 * @throws WTException
	 * @author xucr 
	 * @CreateDate 2020年6月4日
	 */
	@SuppressWarnings("rawtypes")
	public static void cancelControl(NmCommandBean nmcommandbean) throws WTException {
		ArrayList list = nmcommandbean.getSelected();
		FormResult formresult = new FormResult();
	    formresult.setStatus(FormProcessingStatus.SUCCESS);
		
		if (list.size() == 0) {
	            WTMessage s = new WTMessage("ext.tianma.bom.expand.build.MaterielRB", "tip1", null);
	            throw new WTException(s.getLocalizedMessage(SessionHelper.getLocale()));
	    } else {
	    	WorkItem workitem = (WorkItem) nmcommandbean.getPrimaryOid().getRef();
	    	WfAssignedActivity wfAssignedActivity = (WfAssignedActivity) workitem.getSource().getObject();
	    	WfProcess wf = wfAssignedActivity.getParentProcess();
	    	
	    	WTArrayList controllerObjs = (WTArrayList) wf.getContext().getValue( MaterielConstant.notControlledObjs );//人工不受控的对象
	    	if(null == controllerObjs) {
	    		controllerObjs = new WTArrayList();
	    	}
	    	
	    	for(int i = 0; i < list.size(); i++) {
	    		NmContext nmcontext = (NmContext) list.get(i);
	    		WTPart part = (WTPart) nmcontext.getTargetOid().getWtRef().getObject();
	    		if(!controllerObjs.contains(part)) {
	    			controllerObjs.add(part);
	    		}
	    		
	    		ProcessData context = wf.getContext();
		        context.setValue(MaterielConstant.notControlledObjs, controllerObjs);
		    	wf.setContext(context);
		        PersistenceHelper.manager.save(wf);
	    	}
	    }
	}
	
	/**
	 * 手动移除受控内容
	 * @param nmcommandbean
	 * @author xucr
	 * @throws WTException 
	 * @CreateDate 2020年6月4日
	 */
	@SuppressWarnings("rawtypes")
	public static void addControl(NmCommandBean nmcommandbean) throws WTException {
		ArrayList list = nmcommandbean.getSelected();
		FormResult formresult = new FormResult();
	    formresult.setStatus(FormProcessingStatus.SUCCESS);
		
		if (list.size() == 0) {
			WTMessage s = new WTMessage("ext.tianma.bom.expand.build.MaterielRB", "tip2", null);
            throw new WTException(s.getLocalizedMessage(SessionHelper.getLocale()));
	    } else {
	    	WorkItem workitem = (WorkItem) nmcommandbean.getPrimaryOid().getRef();
	    	WfAssignedActivity wfAssignedActivity = (WfAssignedActivity) workitem.getSource().getObject();
	    	WfProcess wf = wfAssignedActivity.getParentProcess();
	    	WTArrayList controlledObjs = (WTArrayList) wf.getContext().getValue( MaterielConstant.notControlledObjs );//人工不受控的对象
	    	if(null != controlledObjs) {
	    		for(int i = 0; i < list.size(); i++) {
		    		NmContext nmcontext = (NmContext) list.get(i);
		    		WTPart part = (WTPart) nmcontext.getTargetOid().getWtRef().getObject();
		    		controlledObjs.remove(part);
		    	}
	    		
		    	ProcessData context = wf.getContext();
		        context.setValue(MaterielConstant.notControlledObjs, controlledObjs);
		    	wf.setContext(context);
		        PersistenceHelper.manager.save(wf);
	    	}

	    }
	}
	
	/**
	 * 发送邮件
	 * @param nmcommandbean
	 * @author xucr
	 * @throws Exception 
	 * @CreateDate 2020年6月16日
	 */
	public static void sendMail(NmCommandBean nmcommandbean) throws Exception {
		//注意：是否是仅有MP时才发送邮件，待确认
		Map<WTUser, WTArrayList> map = getAllUnEffectiveInUser(nmcommandbean);
		if(map.size() > 0) {
			 Set<Entry<WTUser, WTArrayList>> entrySet = map.entrySet();
			 StringBuffer content = new StringBuffer("您好，您在系统中创建的如下物料的图纸还未发布，请尽快发布图纸，以免影响工作进度: \r\n &nbsp;&nbsp;&nbsp;&nbsp;");
			 String titleStr = "您收到他人推送的任务";
			 
			 int count = 1;
			 logger.info("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<邮件发送开始>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
			 logger.info("共"+entrySet.size()+"封邮件");
			 for(Entry<WTUser, WTArrayList> e : entrySet) {
				 WTUser u = e.getKey();
				 WTArrayList parts = e.getValue();
				 
				 for(int i = 0 ; i < parts.size(); i++) {
					 WTPart part = (WTPart) parts.getPersistable(i);
					 content.append(getUrlLink(part, true) + " , ");
				 }
				 
				 SendEmailNotification.sendEmail(u.getEMail(), content.toString(), titleStr);
				 
				 logger.info("第" + count + "封邮件：");
				 logger.info("邮件接收者：" + u.getName());
				 logger.info("接收者邮箱：" + u.getEMail());
				 logger.info("邮件标题：" + titleStr);
				 logger.info("邮件内容：" + content.toString());
				 logger.info("---------------------------------------------------------------------");
				 
				 count ++;
			 }
			 logger.info("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<邮件发送结束>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
		}
	}
	
	public static String getUrlLink (WTPart part, boolean isHTMLTreaty) throws IOException, WTException{
		//http://域名/Windchill/app/#ptc1/tcomp/infoPage?oid=VR%3Awt.part.WTPart:105123&u8=1
		ReferenceFactory rf = new ReferenceFactory();
		String pOid = rf.getReferenceString(part);
		StringBuffer url = new StringBuffer();
		if(isHTMLTreaty){
			WTProperties pro = WTProperties.getLocalProperties();
			String localProperties = pro.getProperty("java.rmi.server.hostname");
			url.append("<a href=").append("http://").append(localProperties).append("/Windchill/app/#ptc1/tcomp/infoPage?oid=")
				.append(pOid).append("&u8=1").append(" target='_blank'>").append(part.getName()).append("</a>");
		}else{
			url.append("<a href=").append("/Windchill/app/#ptc1/tcomp/infoPage?oid=").append(pOid)
				.append("&u8=1").append(" target='_blank'>").append(part.getName()).append("</a>");
		}
		
		return url.toString();
	}
	
	/**
	 * 得到未生效图纸与创建者的信息
	 * @param nmcommandbean
	 * @throws Exception
	 * @author xucr
	 * @CreateDate 2020年6月16日
	 */
	public static Map<WTUser, WTArrayList> getAllUnEffectiveInUser(NmCommandBean nmcommandbean) throws Exception {
		WorkItem workitem = (WorkItem) nmcommandbean.getPrimaryOid().getRef();
		PersistentReference ref = workitem.getPrimaryBusinessObject();
		Map<WTUser, WTArrayList> map = new HashMap<WTUser, WTArrayList>();
		if(ref.getObject() instanceof WTDocument) {
			WTDocument doc = (WTDocument) ref.getObject();//评审对象
			WTArrayList controlledObjs = MaterielTableBuilder.getNotEffective(doc);
			if(null != controlledObjs) {
				WTArrayList partList = null;
				for(int i = 0 ; i < controlledObjs.size(); i++) {
					Object p = controlledObjs.getPersistable(i);
					if(p instanceof WTPart) {
						WTPart part = (WTPart) p;
						WTPart dpart = (WTPart) CoreUtil.getWTPartByNumberAndView(part.getNumber(), "Design");
						WTUser u = (WTUser) dpart.getCreator().getObject();
						
						if(map.containsKey(u)) {
							partList = map.get(u);
							partList.add(dpart);
						} else {
							partList = new WTArrayList();
							partList.add(dpart);
						}
						
						map.put(u, partList);
					}
				}
			}
		}
		return map;
	}
	
	/**
	 * 初始化受控对象
	 * @param pbo
	 * @param self
	 * @param controlledObjs
	 * @param notControlledObjs
	 * @throws Exception
	 * @author xucr
	 * @CreateDate 2020年6月4日
	 */
//	public static void initControl(Object pbo , ObjectReference self, WTArrayList controlledObjs , WTArrayList  notControlledObjs) throws Exception {
//		if(pbo instanceof WTDocument) {
//			WTDocument doc = (WTDocument) pbo;
//			
//			if(null == controlledObjs) {
//				controlledObjs = new WTArrayList();
//			}
//			
//			if(null == notControlledObjs) {
//				notControlledObjs = new WTArrayList();
//			}
//			
//			MaterielTableBuilder.getNotEffective(doc, controlledObjs, notControlledObjs, null);
//			
//			WfProcess wf = BomWorkFlowUtil.getProcess(self);// 获取流程
//	    	ProcessData context = wf.getContext();
//	        context.setValue(MaterielConstant.controlledObjs, controlledObjs);
//	    	wf.setContext(context);
//	        PersistenceHelper.manager.save(wf);
//		}
//	}
	
	public static void initControl(Object pbo , ObjectReference self) throws Exception {
		if(pbo instanceof WTDocument) {
			WTDocument doc = (WTDocument) pbo;
			
			WTArrayList controlledObjs = MaterielTableBuilder.getNotEffective(doc);
			
			WfProcess wf = BomWorkFlowUtil.getProcess(self);// 获取流程
	        ProcessData context = wf.getContext();
	        context.setValue(MaterielConstant.controlledObjs, controlledObjs);
	    	wf.setContext(context);
	        PersistenceHelper.manager.save(wf);
		}
	}
 	
	/**
	 * 校验是否有受控对象的图纸未发放
	 * @param controlledObjs 清单中需要受控对象
	 * @param notControlledObjs 人为设置无需受控对象
	 * @author xucr
	 * @throws WTException 
	 * @CreateDate 2020年6月4日
	 */
	public static void checkControl(WTArrayList controlledObjs , WTArrayList  notControlledObjs) throws WTException {
		String number = "";
		List<String> list = new ArrayList<String>();
		if(null != controlledObjs && controlledObjs.size() > 0) {
			WTReference obj = null;
			WTPart part = null;
			
			for(int i = 0 ; i < controlledObjs.size() ; i++) {
				obj = controlledObjs.getReference(i);
				if(obj.getObject() instanceof WTPart) {
					part = (WTPart) obj.getObject();
					
					if(null == notControlledObjs) {//如果没有手动取消受控对象
						number += part.getNumber() + ",";
						list.add(part.getNumber());
					} else {
						if(!notControlledObjs.contains(part)) {
							number += part.getNumber() + ",";
							list.add(part.getNumber());
						}
					}
				}
			}
			if(list.size() > 0) {
				 throw new WTException("如下原材料对应图纸未生效：" + number);
			}
		}
	}
	
	/**
	 * 判断文档的转量产类型是否MP
	 * @param pbo
	 * @return
	 * @throws RemoteException
	 * @throws WTException
	 * @author xucr
	 * @CreateDate 2020年6月15日
	 */
	public static boolean checkProducttionType(WTDocument doc) throws RemoteException, WTException {
		boolean isMP = false;
		String producttionType = (String) IBAUtil.getIBAValue(doc, "ProducttionType");
		if("MP".equals(producttionType)) {
			isMP = true;
		}
		return isMP;
	}
	
	/**
	 * 判断文档的转量产类型是否MP
	 * @param pbo
	 * @return
	 * @throws RemoteException
	 * @throws WTException
	 * @author xucr
	 * @CreateDate 2020年6月15日
	 */
	public static boolean checkProducttionType(Object pbo) throws RemoteException, WTException {
		boolean isMP = false;
		if(pbo instanceof WTDocument) {
			WTDocument doc = (WTDocument) pbo;
			isMP = checkProducttionType(doc);
		}
		return isMP;
	}
	
	public static void checkControl(ObjectReference self) throws WTException {
		WfProcess wf = BomWorkFlowUtil.getProcess(self);// 获取流程
		
		WTArrayList controlledObjs = (WTArrayList) ( wf.getContext().getValue( MaterielConstant.controlledObjs ) );//未生效对象
		WTArrayList notControlledObjs = (WTArrayList) wf.getContext().getValue( MaterielConstant.notControlledObjs );//人工不受控的对象
		
		checkControl(controlledObjs, notControlledObjs);
	}
	
	/**
	 * 点击确认时的校验
	 * @param pbo
	 * @param self
	 * @throws Exception
	 * @author xucr
	 * @CreateDate 2020年6月15日
	 */
	public static void check(Object pbo, ObjectReference self) throws Exception {
		boolean isMP = checkProducttionType(pbo);// 转量产类型为MP时，才执行此操作
		if(isMP) {
			initControl(pbo, self);
			checkControl(self);
		}
	}
}
